package com.hpsk.shopgen.model.genbasic.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hpsk.common.CommonException;
import com.hpsk.common.CommonPageRequest;
import com.hpsk.shopgen.model.genbasic.entity.GenBasic;
import com.hpsk.shopgen.model.genbasic.dao.GenBasicMapper;
import com.hpsk.shopgen.model.genbasic.enums.GenYesNoEnum;
import com.hpsk.shopgen.model.genbasic.param.GenBasicAddParam;
import com.hpsk.shopgen.model.genbasic.param.GenBasicIdParam;
import com.hpsk.shopgen.model.genbasic.param.GenBasicPageParam;
import com.hpsk.shopgen.model.genbasic.param.GenBasicTableColumnParam;
import com.hpsk.shopgen.model.genbasic.result.GenBasicTableColumnResult;
import com.hpsk.shopgen.model.genbasic.result.GenBasicTableResult;
import com.hpsk.shopgen.model.genbasic.service.IGenBasicService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hpsk.shopgen.model.genbasic.vo.GenBasicVo;
import com.hpsk.shopgen.model.genconfig.entity.GenConfig;
import com.hpsk.shopgen.model.genconfig.param.GenConfigAddParam;
import com.hpsk.shopgen.model.genconfig.service.IGenConfigService;
import com.hpsk.shopgen.utils.GenDbTypeUtil;
import io.github.linpeilie.Converter;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 生成基础 服务实现类
 * </p>
 *
 * @author huangwang
 * @since 2025-07-07
 */
@Service
@AllArgsConstructor(onConstructor_ = @__(@Autowired))
public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> implements IGenBasicService {
    private static final String DB_URL_KEY = "spring.datasource.url";

    private static final String DB_USERNAME_KEY = "spring.datasource.username";

    private static final String DB_PASSWORD_KEY = "spring.datasource.password";

    private static final String TABLE_NAME = "free_shop";
//    private static final String DB_URL_KEY = "spring.datasource.dynamic.datasource.master.url";
//
//    private static final String DB_USERNAME_KEY = "spring.datasource.dynamic.datasource.master.username";
//
//    private static final String DB_PASSWORD_KEY = "spring.datasource.dynamic.datasource.master.password";
private static final String CREATE_USER_KEY = "CREATE_USER";

    private static final String CREATE_TIME_KEY = "CREATE_TIME";

    private static final String UPDATE_USER_KEY = "UPDATE_USER";

    private static final String UPDATE_TIME_KEY = "UPDATE_TIME";

    private static final String DELETE_FLAG_KEY = "DELETE_FLAG";

    @Autowired
    private Environment environment;
    @Resource
    private MybatisPlusProperties mybatisPlusProperties;

    @Setter(onMethod_ = @Autowired)
    private IGenConfigService genConfigService;
    private final Converter converter;

    @Override
    public IPage<GenBasic> page(GenBasicPageParam genBasicPageParam) {
        QueryWrapper<GenBasic> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().orderByAsc(GenBasic::getSortCode);
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public List<GenBasicTableResult> getAllTableInfo() {
        Connection conn = null;
        ResultSet rs = null;
        try {
            conn = DriverManager.getConnection(Objects.requireNonNull(environment.getProperty(DB_URL_KEY)),
                    Objects.requireNonNull(environment.getProperty(DB_USERNAME_KEY)),
                    Objects.requireNonNull(environment.getProperty(DB_PASSWORD_KEY)));
            DatabaseMetaData metaData = conn.getMetaData();
            String url = metaData.getURL();
            String schema = null;
            if (url.toLowerCase().contains("jdbc:oracle")) {
                schema = metaData.getUserName();
            }
            List<GenBasicTableResult> tables = new ArrayList<>();
            rs = metaData.getTables(TABLE_NAME, schema, "%", new String[]{"TABLE"});
            while (rs.next()) {
                String tableName = rs.getString("TABLE_NAME");
                if (!StrUtil.startWithIgnoreCase(tableName, "ACT_")) {
                    GenBasicTableResult genBasicTableResult = new GenBasicTableResult();
                    genBasicTableResult.setTableName(tableName);
                    String remarks = rs.getString("REMARKS");
                    if (ObjectUtil.isEmpty(remarks)) {
                        genBasicTableResult.setTableRemark(tableName);
                    } else {
                        genBasicTableResult.setTableRemark(remarks);
                    }
                    tables.add(genBasicTableResult);
                }
            }
            return tables;
        } catch (SQLException sqlException) {
            sqlException.printStackTrace();
            throw new CommonException("获取数据库表失败");
        } finally {
            JdbcUtils.closeResultSet(rs);
            JdbcUtils.closeConnection(conn);
        }
    }

    @Override
    public List<GenBasicTableColumnResult> tableColumns(String tableName) {
        Connection conn = null;
        ResultSet rs = null;
        try {
            conn = DriverManager.getConnection(Objects.requireNonNull(environment.getProperty(DB_URL_KEY)),
                    Objects.requireNonNull(environment.getProperty(DB_USERNAME_KEY)),
                    Objects.requireNonNull(environment.getProperty(DB_PASSWORD_KEY)));
            DatabaseMetaData metaData = conn.getMetaData();
            String url = metaData.getURL();
            String schema = null;
            if (url.toLowerCase().contains("jdbc:oracle")) {
                schema = metaData.getUserName();
            }
            List<GenBasicTableColumnResult> columns = new ArrayList<>();
            rs = metaData.getColumns(TABLE_NAME, schema, tableName, "%");
            while (rs.next()) {
                String columnName = rs.getString("COLUMN_NAME").toUpperCase();
                GenBasicTableColumnResult genBasicTableColumnResult = new GenBasicTableColumnResult();
                genBasicTableColumnResult.setColumnName(columnName);
                String remarks = rs.getString("REMARKS");
                if (ObjectUtil.isEmpty(remarks)) {
                    genBasicTableColumnResult.setColumnRemark(columnName);
                } else {
                    genBasicTableColumnResult.setColumnRemark(remarks);
                }
                String typeName = rs.getString("TYPE_NAME").toUpperCase();
                if (ObjectUtil.isEmpty(typeName)) {
                    genBasicTableColumnResult.setTypeName("NONE");
                } else {
                    genBasicTableColumnResult.setTypeName(typeName);
                }
                columns.add(genBasicTableColumnResult);
            }
            return columns;
        } catch (SQLException sqlException) {
            sqlException.printStackTrace();
            throw new CommonException("获取数据库表字段失败，表名称：{}", tableName);
        } finally {
            JdbcUtils.closeResultSet(rs);
            JdbcUtils.closeConnection(conn);
        }
    }

    @Override
    public GenBasic add(GenBasicAddParam genBasicAddParam) {
        GenBasic genBasic = BeanUtil.toBean(genBasicAddParam, GenBasic.class);
        this.save(genBasic);
        addGenConfig(genBasic);
        return genBasic;
    }

    @Override
    public GenBasic detail(GenBasicIdParam genBasicIdParam) {
        GenBasic genBasic = getById(genBasicIdParam.getId());
        if(genBasic == null){
            throw new CommonException("生成基础不存在！");
        }
        return genBasic;
    }

    /**
     * 新增表字段至配置内
     *
     * @author 李大鹏
     * @date 2023-05-31 12:32
     */
    private void addGenConfig(GenBasic genBasic) {
        List<GenBasicTableColumnResult> resultList = this.tableColumns(genBasic.getDbTable());
        for (int i = 0; i < resultList.size(); i++) {
            GenBasicTableColumnResult item = resultList.get(i);
            GenConfigAddParam addParam = new GenConfigAddParam();
            addParam.setBasicId(genBasic.getId().toString());
            if (item.getColumnName().equals(genBasic.getDbTableKey())) {
                addParam.setIsTableKey(GenYesNoEnum.Y.getValue());
            } else {
                addParam.setIsTableKey(GenYesNoEnum.N.getValue());
            }
            addParam.setFieldName(item.getColumnName());
            addParam.setFieldType(item.getTypeName());
            addParam.setFieldRemark(item.getColumnRemark());
            // 根据数据库类型获取javaType
            addParam.setFieldJavaType(GenDbTypeUtil.getJavaTypeBySqlType(item.getTypeName()));
            // 根据数据库类型获取组件Type
            addParam.setEffectType(GenDbTypeUtil.getEffectTypeBySqlType(item.getTypeName()));
            // 除主键、删除标志、创建人、创建时间、修改人和修改时间外，所有默认在列表显示、在增改显示、非列省略、非必填，非查询
            String logicDeleteField = mybatisPlusProperties.getGlobalConfig().getDbConfig().getLogicDeleteField();
            if (ObjectUtil.isEmpty(logicDeleteField)) {
                logicDeleteField = "DELETE_FLAG";
            }
            if (genBasic.getDbTableKey().equalsIgnoreCase(item.getColumnName()) ||
                    logicDeleteField.equalsIgnoreCase(item.getColumnName()) ||
                    CREATE_USER_KEY.equalsIgnoreCase(item.getColumnName()) ||
                    CREATE_TIME_KEY.equalsIgnoreCase(item.getColumnName()) ||
                    UPDATE_USER_KEY.equalsIgnoreCase(item.getColumnName()) ||
                    UPDATE_TIME_KEY.equalsIgnoreCase(item.getColumnName())) {
                addParam.setWhetherTable(GenYesNoEnum.N.getValue());
                addParam.setWhetherAddUpdate(GenYesNoEnum.N.getValue());
            } else {
                addParam.setWhetherTable(GenYesNoEnum.Y.getValue());
                addParam.setWhetherAddUpdate(GenYesNoEnum.Y.getValue());
            }
            addParam.setWhetherRetract(GenYesNoEnum.N.getValue());
            addParam.setWhetherRequired(GenYesNoEnum.N.getValue());
            addParam.setQueryWhether(GenYesNoEnum.N.getValue());
            addParam.setSortCode(i);
            GenConfig genConfig = BeanUtil.toBean(addParam, GenConfig.class);
            genConfigService.save(genConfig);
        }
    }
}
